package cn.ztydata.teachingsystem.heaven.service;

import cn.ztydata.teachingsystem.common.Page;
import cn.ztydata.teachingsystem.exception.ServiceException;
import cn.ztydata.teachingsystem.heaven.common.WebContext;
import cn.ztydata.teachingsystem.heaven.cons.GroupType;
import cn.ztydata.teachingsystem.heaven.cons.MediaType;
import cn.ztydata.teachingsystem.heaven.cons.Roles;
import cn.ztydata.teachingsystem.heaven.dao.*;
import cn.ztydata.teachingsystem.heaven.dao.redis.*;
import cn.ztydata.teachingsystem.heaven.entity.*;
import cn.ztydata.teachingsystem.heaven.web.dto.ClassDto;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.sun.xml.internal.bind.v2.runtime.reflect.Lister;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.*;


/**
 * 资源服务类
 * Created by chenxin on 2014/12/1.
 */
@Service
public class ResourceService extends BaseService {
    @Autowired
    private ResourceDao resourceDao;//资源Dao
    @Autowired
    private ResourceInfoDao resourceInfoDao;//资源信息Dao
    @Autowired
    private ResourceTypeDao resourceTypeDao;//资源类型Dao
    @Autowired
    private SpecialtyDao specialtyDao;//专业Dao
    @Autowired
    private RoleDao roleDao;//角色Dao
    @Autowired
    private KpDao kpDao;//知识点Dao
    @Autowired
    private ChapterKpDao chapterKpDao;
    @Autowired
    private ResourceKpDao resourceKpDao;//资源知识点RedisDao
    @Autowired
    private KpResourceDao kpResourceDao;//知识点资源RedisDao
    @Autowired
    private ResourcePVDao resourcePVDao;//资源浏览量RedisDao
    @Autowired
    private ResourceDownloadDao resourceDownloadDao;//资源下载量RedisDao
    @Autowired
    private ResourceChapterDao resourceChapterDao;//资源章节RedisDao
    @Autowired
    private TeacherRscDao teacherRscDao;//教师收藏资源RedisDao
    @Autowired
    private ResExerciseDao resExerciseDao;//资源被习题引用Dao
    @Autowired
    private ClassDao classDao;//班级dao
    @Autowired
    private CourseGroupDao courseGroupDao;//课程群组dao

    @Autowired
    private SpecialtyService specialtyService;//专业服务类
    @Autowired
    private DepartmentService departmentService;//系部服务类
    @Autowired
    private TeacherTeamService teacherTeamService;
    @Autowired
    private KpService kpService;
    @Autowired
    private TeacherService teacherService;
    @Autowired
    private TestDao testDao;
    @Autowired
    private WebContext webContext;
    @Autowired
    private StudentRscDao studentRscDao;
    @Autowired
    private ClassGroupDao classGroupDao;
    @Autowired
    private SpecialtyGroupService specialtyGroupService;

    /**
     * 统计系部资源信息
     * @return Map
     *
     * @author cx
     * @since 2014-12-01
     */
    public Map<Long, Long> countForDept(final Set<Long> deptIdSet) {
        //获取系部的资源总数
        List<Map<String, Object>> rscTotalList = resourceDao.getTotalForDept(deptIdSet);

        //将统计信息转换为“系部ID->资源总量”格式
        Map<Long, Long> deptToRsc = Maps.newHashMap();
        log.debug("循环转换系部资源统计信息格式");
        for (Map<String, Object> rscTotal : rscTotalList) {
            deptToRsc.put((Long)rscTotal.get("deptId"), (Long)rscTotal.get("total"));
        }

        log.debug("return 系部资源统计信息");
        return deptToRsc;
    }

    /**
     * 统计专业资源信息
     * @return Map
     *
     * @author cx
     * @since 2014-12-02
     */
    public Map<Long, Long> countForSpec(final long deptId) {
        //获取系部的资源总数
        List<Map<String, Object>> rscTotalList = resourceDao.getTotalForSpec(deptId);

        //将统计信息转换为“专业ID->资源总量”格式
        Map<Long, Long> specToRsc = Maps.newHashMap();
        log.debug("循环转换专业资源统计格式");
        for (Map<String, Object> rscTotal : rscTotalList) {
            specToRsc.put((Long)rscTotal.get("specId"), (Long)rscTotal.get("total"));
        }

        log.debug("return 专业资源统计map");
        return specToRsc;
    }

    /**
     * 统计专业资源信息
     * @return Map
     *
     * @author fanruiping
     * @since 2014-12-17
     */
    @Cacheable(value = "teachingSystem", key = "'resource:countForSpecialty:'.concat(#keyword).concat(#type).concat(#userId).concat(#role)")
    public  List<Specialty> countForSpec(String keyword,String type, Long userId, int role) {
        List<Specialty> entities = new ArrayList<>();
        List<Specialty> result = new ArrayList<>();
        Set<Long> ids = new HashSet<>();

        //状态集合
        Integer status = null;

        //课程编号集合
        Set<Long> courseId = new HashSet<>();

        //上传者编号集合
        Set<Long> uploaderId = new HashSet<>();

        //专业编号集合
        Set<Long> specialtyId = new HashSet<>();

        if("ALL".equals(type)){
            log.debug("类型为All,即获取所有资源:\"All\".equals(type)");

            status = 1;

            //获取所有专业
            entities = specialtyService.getAll();
        }else if("my".equals(type)){//当前用户的专业资源统计
            uploaderId.add(userId);

            //获取所有专业
            entities = specialtyService.getAll();
        }else{
            if("manage".equals(type)){
                status = 0;
                courseId.add(Long.valueOf(0));
            }else if("ignore".equals(type)){
                status = 2;
            }

            //判断当前用户角色是否是专业负责人
            if(Roles.SPEC_LEADER == role){
                entities = specialtyService.getByLeaderId(userId);
            }
        }

        //判断类型是忽略或负责的 且 专业集合为空
        if(Roles.SPEC_LEADER == role && ("ignore".equals(type) || "manage".equals(type)) && entities.isEmpty()){
            return entities;
        }

        //循环获取专业实体
        for(Specialty entity : entities){
            specialtyId.add(entity.getId());
        }

        //获取专业的资源总数
        List<Map<String, Object>> rscTotalList = resourceDao.getTotalForSpec(keyword,specialtyId,status,courseId,uploaderId);

        log.debug("循环专业统计列表获取重点专业下的资源总量:Map<String, Object> rscTotal : rscTotalList");
        for (Map<String, Object> rscTotal : rscTotalList) {
            Specialty entity = new Specialty();

            entity.setId((Long)rscTotal.get("iSpecialtyId"));
            entity.setName((String)rscTotal.get("sSpecialtyName"));
            entity.setCount((Long)rscTotal.get("total"));

            result.add(entity);

            ids.add((Long)rscTotal.get("iSpecialtyId"));
        }

        //循环为每一个专业填上资源数量
        for(int i=0;i<entities.size();i++){
            if(!ids.contains(entities.get(i).getId())){
                entities.get(i).setCount(Long.valueOf(0));
                result.add(entities.get(i));
            }
        }

        ids.clear();

        log.debug("return specialty->resourceCount map");

        return result;
    }

    /**
     * 统计课程资源信息
     * @return Map
     *
     * @author cx
     * @since 2014-12-02
     */
    public Map<Long, Long> countForCourse(final long specId) {
        //获取课程资源总数
        List<Map<String, Object>> rscTotalList = resourceDao.getTotalForCourse(specId);

        //将统计信息转换为“课程ID->资源总量”格式
        Map<Long, Long> courseToRsc = Maps.newHashMap();
        log.debug("循环转换课程统计信息格式");
        for (Map<String, Object> rscTotal : rscTotalList) {
            courseToRsc.put((Long)rscTotal.get("courseId"), (Long)rscTotal.get("total"));
        }

        log.debug("return 课程统计信息map");
        return courseToRsc;
    }

    /**
     * 统计多个课程的资源总数
     *
     * @author chenxin
     * @since 2015/1/11
     */
    public Map<Long, Long> countForCourses(final Set<Long> courseIdSet) {
        //获取课程资源总数
        List<Map<String, Object>> rscTotalList = resourceDao.getTotalForCourses(courseIdSet);

        //将统计信息转换为“课程ID->资源总量”格式
        Map<Long, Long> courseToRsc = Maps.newHashMap();
        log.debug("循环转换课程统计信息格式");
        for (Map<String, Object> rscTotal : rscTotalList) {
            courseToRsc.put((Long)rscTotal.get("courseId"), (Long)rscTotal.get("total"));
        }

        log.debug("return 课程统计信息map");
        return courseToRsc;
    }

    /**
     * 统计教师上传资源总数
     * @param teacherIdList 教师ID集合
     * @return Map
     *
     * @author cx
     * @since 2014-12-03
     */
    public Map<Long, Long> countForTeacher(final List<Long> teacherIdList) {
        //获取教师资源总数
        List<Map<String, Object>> rscTotalList = resourceDao.getTotalForTeachers(teacherIdList);

        //将统计信息转换为“教师ID->资源总量”格式
        Map<Long, Long> teacherToRsc = Maps.newHashMap();
        log.debug("循环转换教师上传资源统计格式");
        for (Map<String, Object> rscTotal : rscTotalList) {
            teacherToRsc.put((Long)rscTotal.get("teacherId"), (Long)rscTotal.get("total"));
        }

        log.debug("return 教师上传资源统计map");
        return teacherToRsc;
    }

    /**
     * 获取资源数据列表
     * @param user 当前用户
     * @param keyword 关键字
     * @param status 状态
     * @param specialtyId 专业编号
     * @param resourceType 资源类型
     * @param mediaType 媒体类型
     * @param pageNum 页码
     * @param pageSize 每页显示条数
     * @param tag 是否获取当前用户添加的
     * @param showKnowledge 是否显示知识点
     * @return Page
     *
     * @author fanruiping
     * @since 2014-12-05
     */
    public Page<Resource> getList(User user,String keyword, int status, long specialtyId, int resourceType, int mediaType, int pageNum, int pageSize,int tag, boolean showKnowledge){
        Set<Long> specialtyIds = new HashSet<>();//限制专业编号集合
        Long currentUserId = Long.valueOf(0);//当前用户编号

        String mediaStr = MediaType.map.get(mediaType);
        List<String> mediaList = Lists.newArrayList();
        if (mediaStr != null) {
            log.debug("获取到媒体类型:mediaStr != null");

            mediaList = Arrays.asList(StringUtils.split(mediaStr,":"));
        }

        //判断是否限制专业
        if(0 != specialtyId){
            log.debug("专业编号不为0:0 != specialtyId");

            specialtyIds.add(specialtyId);
        }

        //系统资源列表
        if(0 == tag){
            log.debug("获取系统资源列表:0 == tag");

            status = 1;
        }else if(1 == tag){//我的资源列表
            log.debug("获取我的资源列表:1 == tag");

            currentUserId = user.getUserId();
        }else if(2 == tag || 3 == tag){//查看待审核、已忽略列表（未选定专业）
            log.debug("获取待审核或已忽略资源列表:2 == tag || 3 == tag");

            status = 2 == tag ? 0 : 2;//设置状态

            if(0 == specialtyId && Roles.SPEC_LEADER == user.getRole() && roleDao.checkRole(user.getUserId(), Roles.SPEC_LEADER)){
                log.debug("专业编号为0且当前用户是专业负责人");

                //获取专业负责人负责的专业编号集合
                List<Specialty> entities = specialtyDao.getByLeaderId(user.getUserId());

                log.debug("循环专业列表获取专业编号:Specialty entity : entities");
                for (Specialty entity : entities){
                    specialtyIds.add(entity.getId());
                }
            }
        }else{
            log.debug("传递参数有误");

            return new Page<>();
        }

        Page<Resource> page = resourceDao.getList(currentUserId,keyword, status, specialtyIds, resourceType, mediaList, pageNum, pageSize);

        //判断是否需要显示知识点
        if(showKnowledge && page.getCount() > 0){
            log.debug("需要获取资源包含知识点:showKnowledge");

            //资源编号集合
            List<Long> rscIds = new ArrayList<>();

            log.debug("循环获取知识点实体1:Resource resource : page.getItems()");
            for(Resource resource : page.getItems()){
                rscIds.add(resource.getId());
            }

            //获取资源集合包含的知识点集合
            Map<Long,List<KnowledgePoint>> rscKps = this.getKpsByRscIds(rscIds);

            log.debug("循环获取知识点实体2");
            for(Resource resource : page.getItems()){
                //判断资源知识点集合中是否包含指定资源编号
               if(rscKps.containsKey(resource.getId())){
                   log.debug("资源知识点集合中包含指定资源编号:rscKps.containsKey(resource.getId())");

                   resource.setKps(rscKps.get(resource.getId()));
               }else{
                   log.debug("资源知识点集合中不包含指定资源编号");

                   resource.setKps(new ArrayList<KnowledgePoint>());
               }
            }
        }

        log.debug("return resource list");

        return page;
    }

    /**
     * 获取多个资源的知识点集合
     * @param rscIds 资源编号集合
     * @return Map
     *
     * @author fanruiping
     * @since 2015-03-08
     */
    public Map<Long,List<KnowledgePoint>> getKpsByRscIds(List<Long> rscIds){
       Set<Long> kpIds = resourceKpDao.getKpIdsByRscIds(rscIds);

        List<KnowledgePoint> kps = kpService.getAll(new ArrayList<Long>(kpIds));

        Map<Long,KnowledgePoint> knowledgePointMap = new HashMap<>();

        log.debug("循环获取知识点实体:KnowledgePoint knowledgePoint : kps");
        for(KnowledgePoint knowledgePoint : kps){
            knowledgePointMap.put(knowledgePoint.getId(),knowledgePoint);
        }

        Map<Long,List<KnowledgePoint>> rscKps = new HashMap<>();

        log.debug("循环获取资源编号:Long rscId : rscIds");
        for(Long rscId : rscIds){
            Set<Long> rscKpIds = resourceKpDao.getKpIds(rscId);

            log.debug("循环获取资源知识点编号:Long id : rscKpIds");
            for(Long id : rscKpIds){
                if(!rscKps.containsKey(rscId)){
                    log.debug("rscKps中不包含资源编号:!rscKps.containsKey(rscId)");

                    List<KnowledgePoint> knowledgePoints = new ArrayList<>();

                    knowledgePoints.add(knowledgePointMap.get(id));

                    rscKps.put(rscId,knowledgePoints);
                }else{
                    log.debug("rscKps中包含指定资源编号");

                    rscKps.get(rscId).add(knowledgePointMap.get(id));
                }
            }
        }

        return rscKps;
    }

    /**
     * 新增资源
     * @param entity
     *
     * @author fanruiping
     * @since 2014-12-09
     */
    @Transactional
    public void add(Resource entity){
        //根据专业编号获取系部编号
        long deptId = departmentService.getIdBySpecialtyId(entity.getSpecialtyId());
        entity.setDeptId(deptId);

        //获取专业名称
        Specialty specialty = specialtyService.getDetail(entity.getSpecialtyId());
        if(null != specialty){
            log.debug("获取到专业信息:null != specialty");

            entity.setSpecialtyName(specialty.getName());
        }else{
            log.debug("未获取到专业信息:null == specialty");

            log.warn("专业信息不存在");

            throw new ServiceException("专业信息不存在");
        }

        //获取资源类型名称
        ResourceType resourceType = resourceTypeDao.getById(entity.getTypeId());
        if(null != resourceType){
            log.debug("获取到资源类型信息:null != resourceType");

            entity.setTypeName(resourceType.getName());
        }else{
            log.debug("未获取到资源类型信息:null == resourceType");

            log.warn("资源类型信息不存在");

            throw new ServiceException("资源类型信息不存在");
        }

        //获取上传者姓名
        Teacher teacher = teacherService.getDetail(entity.getUploaderId());
        if(null != teacher){
            log.debug("获取到教师信息:null != teacher");

            entity.setUploaderName(teacher.getName());
        }else{
            log.debug("未获取到教师信息:null == teacher");

            log.warn("教师信息不存在");

            throw new ServiceException("教师信息不存在");
        }

        entity.setUploadTime(new Timestamp(System.currentTimeMillis()));//设置添加时间
        entity.setAuditorId(Long.valueOf(0));//审核人编号
        entity.setAuditTime(null);

        //判断资源是课程资源、当前登录用户是超级管理员、或当前用户是否是当前专业的专业负责人,如果是则状态为已通过，否则为未审核
        if((entity.getCourseId() != null && entity.getCourseId() > 0) || webContext.getRole() == Roles.SUPER_ADMIN || roleDao.checkRole(webContext.getUserId(),0) ||
                specialtyService.checkUserIsLeader(entity.getUploaderId(),entity.getSpecialtyId())){
            log.debug("当前资源是课程资源或用户是新增资源所属专业的专业负责人");

            entity.setStatus(1);
            entity.setAuditorId(webContext.getUserId());
            entity.setAuditTime(new Timestamp(System.currentTimeMillis()));
        }else{
            log.debug("当前用户不是新增资源所属专业的专业负责人");

            entity.setStatus(0);

            entity.setCourseId(Long.valueOf(0));
        }

        //判断资源种类是否是知识点，若是则media为”kp“,否则为空
        if(entity.getKind() == 1){
            log.debug("资源种类为知识点");

            entity.setMediaType("kp");
        }

        //向主表中插入记录
        if(!resourceDao.add(entity)){
            log.debug("资源数据新增失败");

            log.warn("资源数据保存失败");

            throw new ServiceException("资源数据保存失败");
        }

        //向明细表插入记录
        if(!resourceInfoDao.add(entity)){
            log.debug("资源详细信息新增失败");

            log.warn("资源详细数据保存失败");

            throw new ServiceException("资源详细数据保存失败");
        }

        //判断资源是否包含知识点
        List<KnowledgePoint> kps = entity.getKps();
        if(!kps.isEmpty()){
            log.debug("资源标签不为空");

            //添加资源与知识点的关系
            resourceKpDao.addKp(entity);
        }
    }

    /**
     * 获取资源明细数据
     * @param id 编号
     * @return Resource
     *
     * @author fanruiping
     * @since 2014-12-09
     */
    public Resource getDetail(long id, int groupType, long groupId){
        Resource entity = resourceDao.getById(id);

        //判断是否获取到资源
        if(null != entity){
            log.debug("resource is exist:null != entity");

            //递增浏览量
            resourcePVDao.incrPV(id);
            //递增key绑定了群组类型、群组ID的浏览量
            resourcePVDao.incrGroupPv(groupType, groupId, id);

            if (groupId == 0) {
                //获取浏览量和下载量
                entity.setPv(resourcePVDao.getPV(id));
            } else {
                entity.setPv(resourcePVDao.getGroupPV(groupType, groupId, id));
            }
            entity.setDownloadCount(resourceDownloadDao.getCount(id));

            //获取包含知识点集合
            List<KnowledgePoint> kps = new ArrayList<>();
            Set<Long> kpIds = resourceKpDao.getKpIds(id);
            if(!kpIds.isEmpty()){
                log.debug("kpIds is not empty:!kpIds.isEmpty()");

                kps = kpDao.getAll(kpIds);
            }
            entity.setKps(kps);


            //获取资源明细信息
            Resource info = resourceInfoDao.getById(id);

            if(null != info){
                log.debug("resource is exist:null != info");

                entity.setOrigin(info.getOrigin());
                entity.setShowAddr(info.getShowAddr());
                entity.setContent(info.getContent());
                entity.setRemark(info.getRemark());
            }
        }

        log.debug("return resource detail");

        return entity;
    }

    /**
     * 获取所有资源类型（不带资源统计）
     * @return List
     *
     * @author fanruiping
     * @since 2015-03-08
     */
    public List<ResourceType> getAllType(){
        log.debug("return all resource type");

        return resourceTypeDao.getAll();
    }

    /**
     * 获取所有资源类型（带资源统计）
     * @return List
     *
     * @author fanruiping
     * @since 2014-12-10
     */
    @Cacheable(value = "teachingSystem", key = "'resource:getAllType:'.concat(#keyword).concat(#majorId).concat(#tag).concat(#userId).concat(#role)")
    public List<ResourceType> getAllType(String keyword, Long majorId, int tag, Long userId, int role){
        int status = 1;//状态（默认：审核通过）

        Long creatorId = Long.valueOf(0);//创建者

        List<Long> majorIds = new ArrayList<>();//限制的专业编号

        //专业编号不为0
        if(0 != majorId){
            log.debug("专业编号不为0:0 != majorId");

            majorIds.add(majorId);
        }

        //我的资源
        if(1 == tag){
            log.debug("标记为1:1 == tag");

            status = 0;

            creatorId = userId;
        }else if(2 == tag || 3 == tag){//待审核/已忽略资源列表
            log.debug("标记为2或为3:2 == tag || 3 == tag");

            status = tag == 2 ? 0 : 2;

            if(0 == majorId && Roles.SPEC_LEADER == role && roleDao.checkRole(userId,Roles.SPEC_LEADER)){
                log.debug("专业编号不为0:0 != majorId");
                //获取专业负责人负责的专业编号集合
                List<Specialty> entities = specialtyDao.getByLeaderId(userId);

                log.debug("循环专业列表获取专业编号:Specialty entity : entities");
                for (Specialty entity : entities){
                    majorIds.add(entity.getId());
                }
            }
        }

        //获取资源类型下的资源总数
        List<Map<String, Object>> rscTotalList = resourceDao.getTotalForType(keyword, majorIds,status,creatorId);

        //将统计信息转换为“资源类型->资源总量”格式
        Map<Long, Long> typeToRsc = Maps.newHashMap();

        log.debug("循环资源类型统计列表获取指定类型下资源总数:Map<String, Object> rscTotal : rscTotalList");
        for (Map<String, Object> rscTotal : rscTotalList) {
            typeToRsc.put((Long)rscTotal.get("iTypeId"), (Long)rscTotal.get("total"));
        }

        //获取所有资源类型
        List<ResourceType> resourceTypes = resourceTypeDao.getAll();

        log.debug("循环所有资源类型获取单个资源类型实体:ResourceType resourceType : resourceTypes");
        for(ResourceType resourceType : resourceTypes){
            //判断是否含有指定资源类型的资源数量
            if(typeToRsc.containsKey(resourceType.getId())){
                log.debug("含有指定资源类型的资源数量:typeToRsc.containsKey(resourceType.getId())");

                resourceType.setCount(typeToRsc.get(resourceType.getId()));
            }else{
                log.debug("没有指定资源类型的资源数量");

                resourceType.setCount(Long.valueOf(0));
            }
        }

        return resourceTypes;
    }

    /**
     * 审核指定资源
     * @param id 资源编号
     * @param auditorId 审核员
     * @param auditTime 审核时间
     * @param status 状态
     * @return int
     *
     * @author fanruiping
     * @since 2014-12-10
     */
    public int audit(long id, long auditorId, Timestamp auditTime, int status){
        log.debug("audit resource by id");

        return resourceDao.setStatus(id, auditorId, auditTime, status);
    }

    /**
     * 判断指定专业下是否含有资源数据
     * @param specialtyId 专业编号
     * @return Boolean
     *
     * @author fanruiping
     * @since 2014-12-12
     */
    public Boolean checkHasResourceBySpecId(long specialtyId){
        log.debug("check specialty has resource");

        return resourceDao.checkBySpecialtyId(specialtyId);
    }

    /**
     * 获取资源的知识点集合
     * @param resourceId 资源编号
     * @return List
     *
     * @author fanruiping
     * @since 2014-12-16
     */
    public List<KnowledgePoint> getKpsByResourceId(Long resourceId){
        Set<Long> kpIds = resourceKpDao.getKpIds(resourceId);

        if(kpIds.isEmpty()){
            return new ArrayList<>();
        }

        return kpDao.getAll(kpIds);
    }

    /**
     * 删除资源指定知识点
     * @param resourceId 资源编号
     * @param kpId 知识点编号
     * @return Boolean
     *
     * @author fanruiping
     * @since 2014-12-16
     */
    public Boolean deleteKp(Long resourceId, Long kpId){
        log.debug("delete resource kp");

        return resourceKpDao.deleteKp(resourceId, kpId);
    }

    /**
     * 获取课程资源列表
     *
     * @author chenxin
     * @since 2014/12/18
     */
    public Page<Resource> getListForCourse(final int pageNum, final int pageSize, final long courseId, final long typeId,
                                           final int mediaType, final String keyword, final String author, final long kpId) {
        //获取知识点关联的资源ID集合
        Set<Long> rscIds = kpResourceDao.getRscIds(kpId);

        //选择知识点过滤条件时，知识点相关的资源没有
        if (kpId != 0 && rscIds.isEmpty()) {
            log.debug("选择知识点过滤条件时，知识点相关的资源没有:kpId != 0 && rscIds.isEmpty()");
            return new Page<>();
        }

        //解析媒体类型
        String mediaStr = MediaType.map.get(mediaType);
        List<String> mediaList = Lists.newArrayList();
        if (mediaStr != null) {
            log.debug("解析媒体类型：mediaStr != null");

            mediaList = Arrays.asList(StringUtils.split(mediaStr,":"));
        }

        //获取课程资源列表
        Page<Resource> page = resourceDao.getListForCourse(pageNum, pageSize, courseId, typeId, mediaList, rscIds, author, keyword);

        //获取资源的知识点
        for (Resource res : page.getItems()) {
            res.setKps(kpService.getKpsForRes(res.getId()));
        }

        log.debug("获取课程资源列表");
        return page;
    }

    /**
     * 获取热门知识点
     * @param count 数量
     * @return List
     *
     * @author fanruiping
     * @since 2014-12-18
     */
    public List<KnowledgePoint> getHotKps(Long count){
        Set<Long> tagIds = kpResourceDao.getOrderByUsedTimes(count);

        if(!tagIds.isEmpty()){
            log.debug("tagId set is not empty:!tagIds.isEmpty()");

            return kpDao.getAll(tagIds);
        }

        log.debug("return empty ArrayList");

        return new ArrayList<>();
    }

    /**
     * 按照媒体类型来统计资源总数
     *
     * @author chenxin
     * @since 2014/12/19
     */
    @Cacheable(value = "teachingSystem:cache:count",key = "'res:byMedia:'.concat(#specId).concat(#courseId)")
    public Map<String, Object> getStatisticForMedia(final long specId, final long courseId) {
        //获取按照媒体类型分类的统计信息
        List<Map<String, Object>> infoList = resourceDao.getTotalForMedia(specId, courseId);

        //初始化媒体类型的资源总数
        Map<Integer, Long> total = Maps.newHashMap();
        total.put(MediaType.AUDIO, Long.valueOf(0));
        total.put(MediaType.VEDIO, Long.valueOf(0));
        total.put(MediaType.PICTURE, Long.valueOf(0));
        total.put(MediaType.TEXT, Long.valueOf(0));

        Map<Integer,Map<String,Long>> mediaTypeCount = new HashMap<>();

        long count = 0;
        log.debug("循环按照媒体类型分类的统计信息：for (Map<String, Object> info : infoList )");
        for (Map<String, Object> info : infoList ) {
            String mediaType = (String) info.get("mediaType");
            long rscTotal = (Long)info.get("total");

            log.debug("遍历资源媒体类型：for (Map.Entry<Integer, String> entry : MediaType.map.entrySet())");
            for (Map.Entry<Integer, String> entry : MediaType.map.entrySet()) {
                if (entry.getValue().contains(mediaType)) {
                    log.debug("如果资源媒体类型包含获取到的媒体类型：entry.getValue().contains(mediaType)");
                    int key = entry.getKey();
                    //追加媒体类型资源总数
                    total.put(key, total.get(key) + rscTotal);

                    if(mediaTypeCount.containsKey(key)){
                        log.debug("比较hashcode为真:mediaTypeCount.containsKey(key)");
                        mediaTypeCount.get(key).put(mediaType,rscTotal);
                    }else{
                        log.debug("比较hashcode为假");
                        Map<String,Long> mediaCount = new HashMap<>();
                        mediaCount.put(mediaType,rscTotal);

                        mediaTypeCount.put(key,mediaCount);
                    }
                }
            }

            count += rscTotal;
        }

        //组合统计结果
        Map<String, Object> result = Maps.newHashMap();

        result.put("total", count);

        List<Map<String, Object>> info = Lists.newArrayList();
        log.debug("遍历媒体类型的资源：for (Map.Entry<Long, Long> entry : total.entrySet())");
        for (Map.Entry<Integer, Long> entry : total.entrySet()) {
            Map<String, Object> entity = Maps.newHashMap();

            entity.put("id", entry.getKey());
            entity.put("count", entry.getValue());

            if(mediaTypeCount.containsKey(entry.getKey())){
                log.debug("mediaTypeCount包含指定媒体类型:mediaTypeCount.containsKey(entry.getKey())");

                entity.put("drilldown",mediaTypeCount.get(entry.getKey()));
            }

            info.add(entity);
        }

        result.put("info", info);

        log.debug("按照媒体类型来统计资源总数");
        return result;
    }

    /**
     * 统计个人的资源总数
     *
     * @author chenxin
     * @since 2015/1/10
     */
    @Cacheable(value = "teachingSystem:cache:count", key = "'res:mine:'.concat(#courseTag)")
    public Map<Integer, Long> getStatisticsForMine(final boolean courseTag) {
        //获取个人的按照媒体类型分类的统计信息
        List<Map<String, Object>> infoList = resourceDao.getTotalForMine(webContext.getUserId(), courseTag);

        //初始化媒体类型的资源总数
        Map<Integer, Long> total = Maps.newHashMap();
        total.put(MediaType.AUDIO, Long.valueOf(0)); //音频
        total.put(MediaType.VEDIO, Long.valueOf(0)); //视频
        total.put(MediaType.PICTURE, Long.valueOf(0)); //图片
        total.put(MediaType.TEXT, Long.valueOf(0)); //文档

        log.debug("循环个人资源统计信息");
        for (Map<String, Object> info : infoList ) {
            String mediaType = (String) info.get("mediaType");
            long rscTotal = (Long)info.get("total");

            log.debug("循环媒体类型");
            for (Map.Entry<Integer, String> entry : MediaType.map.entrySet()) {
                if (entry.getValue().contains(mediaType)) {
                    log.debug("判断扩展名属于哪种媒体类型:entry.getValue().contains(mediaType)");

                    int key = entry.getKey();
                    //追加媒体类型资源总数
                    total.put(key, total.get(key) + rscTotal);
                }
            }
        }

        log.debug("return 个人资源总数");
        return total;
    }

    /**
     * 获取附件详细
     * @param id 资源编号
     * @return Resource
     *
     * @author fanruiping
     * @since 2014-12-22
     */
    public Attachment getAttachmentDetail(Long id){
        log.debug("return attachment detail");

        return resourceDao.getAttachmentById(id);
    }

    /**
     * 更新附件信息
     * @param resource
     * @return Boolean
     *
     * @author fanruiping
     * @since 2014-12-22
     */
    @Transactional
    public void updateAttachment(Attachment resource){
        if(!resourceInfoDao.modify(resource)){
            log.debug("resource info attachment update fail");

            log.error("资源信息数据修改失败");

            throw new ServiceException("资源信息数据修改失败");
        }

        if(!resourceDao.updateAttachment(resource)){
            log.debug("resource attachment update fail");

            log.error("资源数据修改失败");

            throw new ServiceException("资源数据修改失败");
        }
    }

    /**
     * 获取最新资源列表
     * @param count 数量
     * @return List
     *
     * @author fanruiping
     * @since 2014-12-22
     */
    public List<Resource> getNewestList(int count){
        log.debug("return newest resource list by count");

        return resourceDao.getNewestList(count);
    }

    /**
     * 删除指定资源及其相关数据
     * @param id 资源编号
     * @return boolean
     *
     * @author fanruiping
     * @since 2014-12-23
     */
    @CacheEvict(value = "teachingSystem:cache:kp", key = "'forRes:'.concat(#id)")
    public void deleteById(Long id){
        //判断资源是否已经被使用(课程、章节、习题和作业)
        if(resourceDao.getCourseIdById(id) > 0   || resourceChapterDao.isUsed(id) || resExerciseDao.isUsed(id)
                || testDao.isQuoteByRscId(id) > 0){
            log.debug("资源已经被使用(课程、章节、习题和作业)");

            //设置资源无效
            if(!resourceDao.setInvalid(id)){
                log.debug("设置资源无效状态失败");

                throw new  ServiceException("设置资源无效状态失败");
            }

            throw new ServiceException("资源现被使用(课程、章节、习题或作业),已将该资源设置为无效数据");
        }else{

            //删除资源与知识点的关系
            if(!resourceKpDao.deleteKps(id)){
                log.debug("资源=》知识点关系删除失败");

                log.warn("资源=》知识点关系删除失败");

                throw new ServiceException("资源=》知识点关系删除失败");
            }

            //删除资源详细数据
            if(resourceInfoDao.delete(id) == -1){
                log.debug("resource delete fail");

                log.warn("资源详细数据删除失败");

                throw new ServiceException("资源详细数据删除失败");
            }

            //删除资源数据
            if(resourceDao.delete(id) == -1){
                log.debug("resource info delete fail");

                log.warn("资源数据删除失败");

                throw new ServiceException("资源数据删除失败");
            }
        }
    }

    /**
     * 递增资源下载量
     * @param resourceId 资源编号
     *
     * @author fanruiping
     * @since 2014-12-24
     */
    public void incrDownloadCnt(Long resourceId){
        log.debug("递增资源下载量");

        resourceDownloadDao.incrCount(resourceId);
    }

    /**
     * 删除课程资源
     *
     * @author chenxin
     * @since 2014/12/24
     */
    public void deleteForCourse(final long rscId, final long courseId) {
        //判断用户是否在课程的教师团队
        teacherTeamService.isMemeber(courseId);

        if (!resourceDao.updateCourseId(rscId, courseId)) {
            log.debug("删除课程资源失败:!resourceDao.updateCourseId(rscId, courseId)");
            log.warn("删除课程资源失败:rscId->" + rscId + ",courseId->" + courseId);
            throw new ServiceException();
        }
    }

    /**
     * 搜索资源（章节）
     *
     * @author chenxin
     * @since 2015/1/10
     */
    public Page<Resource> getListForSearch(final int pageNum, final int pageSize, final long courseId, final long nodeId, final long typeId,
                                           final int mediaType, final String keyword, final boolean related, final boolean rscTag) {
        //判断是否关联章节知识点
        Set<Long> rscIds = Sets.newHashSet();
        if (related) {
            log.debug("关联章节知识点搜索:related");

            //获取章节的知识点ID集合
            Set<Long> kpIds = chapterKpDao.getKpIds(nodeId);

            log.debug("循环绑定知识点资源ID集合");

            //获取绑定知识点的资源ID集合
            for (Long kpId : kpIds) {
                Set<Long> rscSet = kpResourceDao.getRscIds(kpId);
                rscIds.addAll(rscSet);
            }
        }

        //解析媒体类型
        String mediaStr = MediaType.map.get(mediaType);
        List<String> mediaList = Lists.newArrayList();
        if (mediaStr != null) {
            log.debug("解析媒体类型：mediaStr != null");
            mediaList = Arrays.asList(StringUtils.split(mediaStr, ":"));
        }

        //获取资源分页列表
        Page<Resource> page = resourceDao.getListForChapter(pageNum, pageSize, courseId, typeId, mediaList, rscIds, keyword, rscTag);

        //获取资源的知识点信息
        for (Resource res : page.getItems()) {
            res.setKps(kpService.getKpsForRes(res.getId()));
        }

        log.debug("获取课程资源列表");
        return page;
    }

    /**
     * 获取知识点关联的资源列表
     *
     * @author chenxin
     * @since 2015/2/9
     */
    public Page<Resource> getListByKps(final int pageNum, final int pageSize, List<Long> kpIds) {
        //获取知识点关联的资源ID并集
        Set<Long> unionIds = kpResourceDao.getResIdsByUnion(kpIds);

        if (unionIds == null || unionIds.isEmpty()) {
            return new Page<>();
        }

        //根据习题ID获取资源信息
        Page<Resource> resources = resourceDao.getValidResources(pageNum, pageSize, 0, unionIds, null, 0);

        log.debug("循环获取资源实体:Resource res : resources");
        //获取每个资源的知识点
        for (Resource res : resources.getItems()) {
            res.setKps(kpService.getKpsForRes(res.getId()));
        }

        log.debug("return resourceList by kps");

        return resources;
    }


    /**
     * 教师收藏资源
     * @param teacherId 教师编号
     * @param resourceId 资源编号
     * @return boolean
     *
     * @author fanruiping
     * @since 2015-02-05
     */
    public boolean collect(long teacherId, long resourceId){
        log.debug("返回教师收藏指定资源结果");

        Resource resource = resourceDao.getById(resourceId);

        if(null == resource){
            return false;
        }

        //群组编号
        Long groupId = groupId = resource.getSpecialtyId();
        //群组类型
        int groupType = 0;

        return teacherRscDao.addResource(teacherId, resourceId,groupId,groupType);
    }

    /**
     * 教师是否收藏指定资源
     * @param teacherId 教师编号
     * @param resourceId 资源编号
     * @return boolean
     *
     * @author fanruiping
     * @since 2015-02-10
     */
    public boolean isCollected(long teacherId, long resourceId){
        log.debug("返回教师是否已收藏指定资源");

        Resource resource = resourceDao.getById(resourceId);

        if(null == resource){
            return false;
        }

        //群组编号
        Long groupId = groupId = resource.getSpecialtyId();
        //群组类型
        int groupType = 0;

        return teacherRscDao.isCollected(teacherId, resourceId,groupId,groupType);
    }

    /**
     * 取消当前用户收藏资源
     * @param resourceId 资源编号
     * @return boolean
     *
     * @author fanruiping
     * @since 2015-05-08
     */
    public boolean cancelCollect(long resourceId){
        Resource resource = resourceDao.getById(resourceId);

        if(null == resource){
            return false;
        }

        //群组编号
        Long groupId = groupId = resource.getSpecialtyId();
        //群组类型
        int groupType = 0;

        //当前用户是学生
        if(Roles.STUDENT == webContext.getRole()){
            return studentRscDao.deleteResource(webContext.getUserId(),resourceId,groupId,groupType);
        }else{//当前用户是教师
            return teacherRscDao.deleteResource(webContext.getUserId(),resourceId,groupId,groupType);
        }
    }

	/**
     * 线下作业引用资源
     * @param specialtyId 专业编号
     * @param pageNum 页码
     * @param pageSize 每页显示条数
     * @return Page
     *
     * @author fanruiping
     * @since 2015-03-31
     */
    public Page<Resource> getRecommendForTest(Long specialtyId, int pageNum, int pageSize){
        //资源类型
        Set<Integer> types = new HashSet<>();
        types.add(5);
        types.add(23);

        //媒体类型
        Set<String> medias = new HashSet<>();
        medias.add("doc");
        medias.add("docx");
        medias.add("rtf");

        Page<Resource> page = resourceDao.recommendListForTest(specialtyId,medias,types,pageNum,pageSize);

        //判断数据条数
        if(page.getTotal() == 0){
            log.debug("数据条数为0:page.getTotal() == 0");

            return new Page<>();
        }

        List<Long> rscIds = new ArrayList<>();

        log.debug("循环资源列表获取资源编号集合");
        //循环获取资源编号
        for(Resource resource : page.getItems()){
            rscIds.add(resource.getId());
        }

        //获取资源集合包含的知识点集合
        Map<Long,List<KnowledgePoint>> rscKps = this.getKpsByRscIds(rscIds);

        log.debug("循环资源列表集合插入知识点数据集合");
        for(Resource resource : page.getItems()){
            resource.setKps(rscKps.get(resource.getId()));
        }

        return page;
	}	

    /**
     * 获取新建作业时资源推荐列表
     * 
     * @param pageNum 当前页码
     * @param pageSize 每页条数
     * @param specId 专业ID
     * @param kpIds 知识点ID
     * @return Page
     * 
     * @author cx
     * @since 2015/4/6
     */
    public Page<Resource> getListForTestCreate(final int pageNum, final int pageSize, final long specId, final List<Long> kpIds) {
        //获取知识点关联的资源ID并集
        Set<Long> unionIds = kpResourceDao.getResIdsByUnion(kpIds);
        if (unionIds == null || unionIds.isEmpty()) {
            log.debug("unionIds == null || unionIds.isEmpty()");

            log.warn("知识点关联资源为空:kpIds->{}", kpIds);
            throw new ServiceException("暂无推荐资源");
        }

        //获取资源类型为“习题作业”的ID
        Long resTypeId = resourceTypeDao.getIdByName("习题作业");
        //资源媒体类型为word
        List<String> mediaList = Lists.newArrayList(MediaType.MEDIA_WORD);

        //获取资源分页集合
        Page<Resource> resPageList = resourceDao.getValidResources(pageNum, pageSize, resTypeId, unionIds, mediaList, specId);

        log.debug("循环资源分页集合");
        //获取每个资源的知识点
        for (Resource res : resPageList.getItems()) {
            res.setKps(kpService.getKpsForRes(res.getId()));
        }

        log.debug("获取新建作业时资源推荐列表");
        return resPageList;
    }


    //<editor-fold desc="creator by lyj">


    //<editor-fold desc="验证">
    /**
     * 验证角色
     * @param groupType 群组类型
     * @return void
     * @author lyj
     * @since 2015-5-7
     */
    public void checkRole(final int groupType) {
        //角色验证
        Boolean checkRole = true;
        if (groupType == GroupType.CLASS_GROUP || groupType == GroupType.COURSE_GROUP) {
            log.debug("groupType == GroupType.CLASS_GROUP || groupType == GroupType.COURSE_GROUP");

            if (webContext.getRole() != Roles.TEACHER && webContext.getRole() != Roles.STUDENT) {
                log.debug("webContext.getRole() != Roles.TEACHER && webContext.getRole() != Roles.STUDENT");
                checkRole = false;
            }
        } else if (groupType == GroupType.SPEC_GROUP) {
            log.debug("groupType == GroupType.SPEC_GROUP");

            if (webContext.getRole() != Roles.SPEC_LEADER && webContext.getRole() != Roles.TEACHER) {
                log.debug("webContext.getRole() != Roles.SPEC_LEADER && webContext.getRole() != Roles.TEACHER");
                checkRole = false;
            }
        }

        if (!checkRole){
            log.debug("当前登录用户没有权限使用该功能!checkRole");

            log.warn("当前登录用户没有权限使用该功能！");
            throw new ServiceException("权限错误！");
        }
    }
    //</editor-fold>


    /**
     * 获取群组资源列表
     *
     * @param groupType 群组类型（0费群组1课程群组2专业群组3班级群组）
     * @param groupId 群组ID
     * @param tag 标记（0全部1我的2收藏）
     * @param typeId 资源类型ID
     * @param keyword 关键字(资源名称)
     * @param pageNum 当前页码
     * @param pageSize 每页条数
     * @return JsonResultList
     * @author lyj
     * @since 2015-3-31
     */
    public Page<Resource> getGroupResource(final int groupType, final long groupId, final int tag, final long typeId, final String keyword, final int pageNum, final int pageSize, final User userInfo) {

        checkRole(groupType);

        //判断登录用户是否可以获取该课程群组信息
        if (groupType == GroupType.COURSE_GROUP) { //验证课程群组

            if (courseGroupDao.checkGroupIdIsNum(groupId, userInfo.getNumber()) == 0) {
                throw new ServiceException("权限错误！");
            }

        } else if (groupType == GroupType.CLASS_GROUP) { //验证班级群组

            //判断登录用户是否可以获取该班级群组信息
            if (classGroupDao.checkGroupIdIsNum(groupId, userInfo.getNumber()) == 0) {
                throw new ServiceException("权限错误！");
            }
        } else if (groupType == GroupType.SPEC_GROUP) { //验证专业群组

            //判断登录用户是否可以获取该专业群组信息
            if (!specialtyGroupService.getSpecialtyIds(userInfo).contains(groupId)) {
                throw new ServiceException("权限错误！");
            }
        }

        long upLoaderId = 0; //资源上传者ID
        int role = 0; //角色

        List<Long> rscIds = new ArrayList<>(); //被收藏的资源ID集合


        //判断tag标记
        if (tag == 1) {
            log.debug("判断tag标记");
            //获取我的资源
            upLoaderId = webContext.getUserId();
            role = webContext.getRole() == Roles.STUDENT ? 1 : 0;
        } else if (tag == 2) { //我的收藏
            log.debug("我的收藏tag == 2");
            //获取我收藏的资源ID集合
            if (webContext.getRole() == Roles.STUDENT) {
                log.debug("获取我收藏的资源ID集合webContext.getRole() == Roles.STUDENT");
                rscIds = studentRscDao.getAll(webContext.getUserId(), groupId, groupType);
            } else {
                log.debug("获取我收藏的资源ID集合webContext.getRole() != Roles.STUDENT");
                rscIds = teacherRscDao.getAll(webContext.getUserId(), groupId, groupType);
            }

            if (rscIds.size() == 0) {
                log.debug("rscIds.size() == 0");
                return new Page<>();
            }
        }

        Page<Resource> page = resourceDao.getGroupList(groupType, groupId, upLoaderId, role, typeId, keyword, pageNum, pageSize, rscIds);

        //获取被收藏的资源ＩＤ集合
        if (webContext.getRole() == Roles.STUDENT) {
            log.debug("获取被收藏的资源ＩＤ集合webContext.getRole() == Roles.STUDENT");
            rscIds = studentRscDao.getAll(webContext.getUserId(), groupId, groupType);
        } else {
            log.debug("获取被收藏的资源ＩＤ集合webContext.getRole() != Roles.STUDENT");
            rscIds = teacherRscDao.getAll(webContext.getUserId(), groupId, groupType);
        }

        //循环判断资源是否已被收藏
        log.debug("循环判断资源是否已被收藏");
        for (Resource resource : page.getItems()) {
            if (rscIds.contains(resource.getId())) {
                resource.setBest(1);
            }
        }

        log.debug("获取群组资源列表");
        return page;

    }


    /**
     * 推荐资源
     *
     * @param mapCommend
     * @return int
     * @author lyj
     * @since 2015-3-31
     */
    public void recommend(final Map<String, Object> mapCommend) {

        if ((int) mapCommend.get("groupType") == GroupType.COURSE_GROUP) {
            log.debug("(int) mapCommend.get(\"groupType\") == GroupType.CLASS_GROUP");

            if (webContext.getRole() != Roles.TEACHER) {
                log.debug("推荐资源权限错误webContext.getRole() != Roles.TEACHER");

                log.warn("推荐资源权限错误！");
                throw new ServiceException("权限错误！");
            }
        } else if ((int) mapCommend.get("groupType") == GroupType.SPEC_GROUP) {
            log.debug("(int) mapCommend.get(\"groupType\") == GroupType.SPEC_GROUP");

            if (webContext.getRole() != Roles.SPEC_LEADER) {
                log.debug("推荐资源权限错误webContext.getRole() != Roles.SPEC_LEADER");

                log.warn("推荐资源权限错误！");
                throw new ServiceException("权限错误！");
            }
        } else {
            throw new ServiceException("该群组没有推荐功能！");
        }


        if (resourceDao.getById(Long.parseLong(mapCommend.get("id").toString())) == null) {
            log.debug("资源已经被删除resourceDao.getById(Long.parseLong(mapCommend.get(\"id\").toString())) == null");
            throw new ServiceException("资源已经被删除！");
        }

        if (resourceDao.recommend(mapCommend) != 1) {
            log.debug("推荐资源失败resourceDao.recommend(mapCommend) != 1");
            log.warn("推荐资源失败！");
            throw new ServiceException();
        }
    }


    /**
     * 是否收藏资源
     *
     * @param rscId 资源ID
     * @return void
     * @author lyj
     * @since 2015-3-31
     */
    public void collection(final long rscId, final int best, final long groupId, final int groupType) {

        checkRole(groupType);

        //判断资源是否已经被删除
        if (resourceDao.getById(rscId) == null) {
            log.debug("资源已经被删除resourceDao.getById(rscId) == null");
            throw new ServiceException("资源已经被删除！");
        }

        if (best == 0) {
            log.debug("取消收藏资源best == 0");
            //取消收藏资源
            deleteCollect(rscId, groupId, groupType);
        } else {
            log.debug("收藏资源");
            //收藏资源
            addCollect(rscId, groupId, groupType);
        }

    }


    /**
     * 取消收藏资源
     * @param rscId 资源ID
     * @author lyj
     * @since 2015-4-3
     */
    public void deleteCollect(final long rscId, final long groupId, final int groupType) {
        if (webContext.getRole() == Roles.STUDENT) {
            log.debug("取消收藏资源webContext.getRole() == Roles.STUDENT");

            if (!studentRscDao.deleteResource(webContext.getUserId(), rscId, groupId, groupType)) {
                log.debug("取消收藏失败!studentRscDao.deleteResource(webContext.getUserId(), rscId)");

                log.warn("取消收藏失败！userId->{},role->{}", webContext.getUserId(), webContext.getRole());
                throw new ServiceException("取消收藏失败！");
            }
        } else {
            log.debug("取消收藏资源webContext.getRole() != Roles.STUDENT");

            if (!teacherRscDao.deleteResource(webContext.getUserId(), rscId, groupId, groupType)) {
                log.debug("取消收藏失败!teacherRscDao.deleteResource(webContext.getUserId(), rscId)");

                log.warn("取消收藏失败！userId->{},role->{}", webContext.getUserId(), webContext.getRole());
                throw new ServiceException("取消收藏失败！");
            }
        }
    }


    /**
     * 收藏资源
     *
     * @param rscId 资源ID
     * @author lyj
     * @since 2015-4-3
     */
    public void addCollect(final long rscId, final long groupId, final int groupType){
        //如果登录用户是学生，收藏到学生收藏表
        if (webContext.getRole() == Roles.STUDENT){
            log.debug("如果登录用户是学生，收藏到学生收藏表webContext.getRole() == Roles.STUDENT");

            //判断资源是否已经被收藏
            if (studentRscDao.isCollected(webContext.getUserId(), rscId, groupId, groupType)){
                log.debug("判断资源是否已经被收藏studentRscDao.isCollected(webContext.getUserId(), rscId)");
                log.warn("资源已经被收藏！userId->{},rscId->{}", webContext.getUserId(), rscId);
                throw new ServiceException("资源已经被收藏！");
            }

            //收藏资源
            if (!studentRscDao.addResource(webContext.getUserId(), rscId, groupId, groupType)){
                log.debug("收藏资源失败!studentRscDao.addResource(webContext.getUserId(), rscId)");
                log.warn("收藏资源失败！userId->{},role->{}", webContext.getUserId(), webContext.getRole());
                throw new ServiceException("收藏失败！");
            }
        } else { //如果登录用户是老师收藏到老师收藏表

            log.debug("如果登录用户是老师收藏到老师收藏表");
            //判断资源是否已经被收藏
            if (teacherRscDao.isCollected(webContext.getUserId(), rscId, groupId, groupType)){
                log.debug("判断资源是否已经被收藏teacherRscDao.isCollected(webContext.getUserId(), rscId)");
                log.warn("资源已经被收藏！userId->{},rscId->{}", webContext.getUserId(), rscId);
                throw new ServiceException("资源已经被收藏！");
            }

            //收藏资源
            if (!teacherRscDao.addResource(webContext.getUserId(), rscId, groupId, groupType)) {
                log.debug("收藏资源!teacherRscDao.addResource(webContext.getUserId(), rscId)");
                log.warn("收藏资源失败！userId->{},role->{}", webContext.getUserId(), webContext.getRole());
                throw new ServiceException("收藏失败！");
            }
        }
    }


    /**
     * 获取热门资源列表
     *
     * @param groupType 群组类型
     * @param groupId 群组ID
     * @param count 条数
     * @return List<Long>
     * @author lyj
     * @since 2015-4-1
     */
    public List<Resource> getHotRsc(final int groupType, final long groupId, final int count, final User userInfo) {

        checkRole(groupType);


        //判断登录用户是否可以获取该课程群组信息
        if (groupType == GroupType.COURSE_GROUP) { //验证课程群组
            if (courseGroupDao.checkGroupIdIsNum(groupId, userInfo.getNumber()) == 0) {
                throw new ServiceException("权限错误！");
            }
        } else if (groupType == GroupType.CLASS_GROUP) { //验证班级群组

            //判断登录用户是否可以获取该班级群组信息
            if (classGroupDao.checkGroupIdIsNum(groupId, userInfo.getNumber()) == 0) {
                throw new ServiceException("权限错误！");
            }
        } else if (groupType == GroupType.SPEC_GROUP) { //验证专业群组

            //判断登录用户是否可以获取该专业群组信息
            if (!specialtyGroupService.getSpecialtyIds(userInfo).contains(groupId)) {
                throw new ServiceException("权限错误！");
            }
        }

        //获取前几条热门资源ID
        Set<Long> rscIds = resourcePVDao.getOrderByUsedTimes(groupType, groupId, count);

        if (!rscIds.isEmpty()) {

            log.debug("!rscIds.isEmpty()");
            List<Resource> resourceList = resourceDao.getHotList(rscIds, 0); //根据资源ID获取资源信息

            //绑定资源浏览量
            log.debug("绑定资源浏览量");
            for (Resource resource : resourceList) {
                resource.setPv(resourcePVDao.getGroupPV(groupType, groupId, resource.getId()));
            }

            //根据浏览量排序
            Collections.sort(resourceList, new Comparator<Resource>() {
                public int compare(Resource arg1, Resource arg0) {
                    return arg0.getPv().compareTo(arg1.getPv());
                }
            });

            log.debug("获取热门资源列表");
            return resourceList;
        } else {

            List<Resource> resourceList = resourceDao.getHotList(rscIds, count); //根据资源ID获取资源信息

            //绑定资源浏览量
            log.debug("绑定资源浏览量");
            for (Resource resource : resourceList) {
                resource.setPv(0);
            }

            log.debug("获取热门资源列表");
            return resourceList;
        }

    }



    /**
     * 新增资源
     * @param entity
     *
     * @author lyj
     * @since 2015-4-3
     */
    @Transactional
    public void addGroupResource(Resource entity, User userInfo) {

        //验证角色
        checkRole(entity.getGroupType());

        //填充上传者ID
        entity.setUploaderId(webContext.getUserId());
        //填充审核人
        entity.setAuditorId(Long.valueOf(0));
        //填充审核时间
        entity.setAuditTime(null);

        //填充上传者姓名
        entity.setUploaderName(userInfo.getName());
        //填充角色
        entity.setRole(webContext.getRole() == Roles.STUDENT ? 1 : 0);

        //如果登录用户是老师且群组类型不是班级群组
        if (webContext.getRole() != Roles.STUDENT && GroupType.CLASS_GROUP != entity.getGroupType()) {

            //判断当前用户是否是超级管理员或当前专业的专业负责人,如果是则状态为已通过，否则为未审核
            if (Roles.SUPER_ADMIN == webContext.getRole() || roleDao.checkRole(webContext.getUserId(), Roles.SUPER_ADMIN) ||
                    specialtyService.checkUserIsLeader(entity.getUploaderId(), entity.getSpecialtyId())) {
                entity.setStatus(1);
                entity.setRecommended(1);
                entity.setAuditorId(webContext.getUserId());
                entity.setAuditTime(new Timestamp(System.currentTimeMillis()));
            } else {
                log.debug("判断当前用户是否是当前专业的专业负责人");
                entity.setStatus(0);
                entity.setCourseId(Long.valueOf(0));
                entity.setRecommended(0); //默认不是推荐资源
            }

        } else { //如果登录用户是学生
            log.debug("如果登录用户是学生");
            entity.setRecommended(0); //默认不是推荐资源
            entity.setStatus(0); //默认处理状态是0（0：未处理，-1：失败，1：处理中，2：完成）
        }

        //判断资源种类是否是知识点，若是则media为”kp“,否则为空
        if (entity.getKind() == 1) {
            log.debug("判断资源种类是否是知识点entity.getKind() == 1");
            entity.setMediaType("kp");
        } else {
            log.debug("判断资源种类是否是知识点");
            entity.setMediaType("");
        }

        //向主表中插入记录
        if (!resourceDao.addGroupResource(entity)) {
            log.debug("向主表中插入记录!resourceDao.addGroupResource(entity)");
            throw new ServiceException("资源数据保存失败");
        }

        //向明细表插入记录
        if (!resourceInfoDao.add(entity)) {
            log.debug("向明细表插入记录!resourceInfoDao.add(entity)");
            throw new ServiceException("资源详细数据保存失败");
        }

        //判断资源是否包含知识点
        List<KnowledgePoint> kps = entity.getKps();
        if (!kps.isEmpty()) {
            log.debug("判断资源是否包含知识点!kps.isEmpty()");
            //添加资源与知识点的关系
            resourceKpDao.addKp(entity);
        }

        resourcePVDao.incrGroupPv(entity.getGroupType(), entity.getGroupId(), entity.getId());
    }

    /**
     * 我的资源统计图（学生）
     *
     * @param type (0课程群组资源 1班级资源-暂时不做）
     * @param groupId
     * @return map
     * @author lyj
     * @since 2015-4-15
     */
    public Map<String, Object> getStudentResourceChart(final int type, final long groupId, final User userInfo) {

        if (webContext.getRole() != Roles.STUDENT) {
            log.debug("webContext.getRole() != Roles.SUPER_ADMIN && webContext.getRole() != Roles.STUDENT");
            throw new ServiceException("权限错误！");
        }

        //判断登录用户是否可以获取该课程群组信息
        if (type == 0) { //验证课程群组
            if (courseGroupDao.checkGroupIdIsNum(groupId, userInfo.getNumber()) == 0) {
                throw new ServiceException("权限错误！");
            }
        } else if (type == 1) { //验证班级群组

            //判断登录用户是否可以获取该班级群组信息
            if (classGroupDao.checkGroupIdIsNum(groupId, userInfo.getNumber()) == 0) {
                throw new ServiceException("权限错误！");
            }
        }

        List<Map<String, Object>> infoList = new ArrayList<>();
        //获取按照媒体类型分类的统计信息
        if (type == 0) {
            log.debug("获取按照媒体类型分类的统计信息type == 0");

            infoList = resourceDao.getTotalForMedia(groupId, GroupType.COURSE_GROUP);
        } else {
            log.debug("type != 0");

            infoList = resourceDao.getTotalForMedia(groupId, GroupType.CLASS_GROUP);
        }

        log.debug("我的资源统计图type == 0");

        //初始化媒体类型的资源总数
        Map<Integer, Long> total = Maps.newHashMap();
        total.put(MediaType.AUDIO, Long.valueOf(0));
        total.put(MediaType.VEDIO, Long.valueOf(0));
        total.put(MediaType.PICTURE, Long.valueOf(0));
        total.put(MediaType.TEXT, Long.valueOf(0));

        Map<Integer, Map<String, Long>> mediaTypeCount = new HashMap<>();

        long count = 0; //存储资源总数
        log.debug("循环统计信息");
        for (Map<String, Object> info : infoList) {
            String mediaType = (String) info.get("mediaType");
            long rscTotal = (Long) info.get("total"); //某个媒体类型的资源数如（MP3：4个资源， wmv:5个资源）

            log.debug("循环类型");
            for (Map.Entry<Integer, String> entry : MediaType.map.entrySet()) {
                if (entry.getValue().contains(mediaType)) {
                    log.debug("entry.getValue().contains(mediaType)");
                    int key = entry.getKey();

                    //追加媒体类型资源总数
                    total.put(key, total.get(key) + rscTotal);

                    if (mediaTypeCount.containsKey(key)) {
                        log.debug("mediaTypeCount.containsKey(key)");
                        mediaTypeCount.get(key).put(mediaType, rscTotal);
                    } else {
                        log.debug("!mediaTypeCount.containsKey(key)");
                        Map<String, Long> mediaCount = new HashMap<>();
                        mediaCount.put(mediaType, rscTotal);

                        mediaTypeCount.put(key, mediaCount);
                    }
                }
            }

            count += rscTotal;
        }

        //组合统计结果
        Map<String, Object> result = Maps.newHashMap();

        result.put("total", count);

        List<Map<String, Object>> info = Lists.newArrayList();
        log.debug("循环entrySet()");
        for (Map.Entry<Integer, Long> entry : total.entrySet()) {
            Map<String, Object> entity = Maps.newHashMap();

            entity.put("id", entry.getKey());
            entity.put("count", entry.getValue());

            if (mediaTypeCount.containsKey(entry.getKey())) {
                log.debug("mediaTypeCount.containsKey(entry.getKey())");
                entity.put("drilldown", mediaTypeCount.get(entry.getKey()));
            }

            info.add(entity);
        }

        result.put("info", info);

        log.debug("返回result");
        return result;
    }
    //</editor-fold>

    //<editor-fold desc="creator by frp">
    /**
     * 按照媒体类型来统计资源总数
     * @param groupType 群组类型（0：专业、1：课程、2：专业群组、3：班级）
     * @return Map
     *
     * @author fanruiping
     * @since 2015-05-05
     */
    public Map<String, Object> getStatisticForMediaByGroup(final int groupType) {
        //判断当前用户是院系用户或角色是学生要查看专业群组数据
        if(webContext.getRole() == Roles.COLLEGE_USER || (groupType == 2 && Roles.STUDENT == webContext.getRole())){
            log.debug("当前用户为院级用户或当前用户为学生且群组类型为专业群组时，无权查看");

            throw new ServiceException("当前用户无权查看该统计数据");
        }

        int role = 0;//创建人角色

        //判断当前用户为学生
        if(Roles.STUDENT ==  webContext.getRole()){
            log.debug("当前用户为学生:Roles.STUDENT ==  webContext.getRole()");

            role = 1;
        }

        //获取按照媒体类型分类的统计信息
        List<Map<String, Object>> infoList = resourceDao.getTotalForMediaByGroup(role,webContext.getUserId(),groupType);

        //初始化媒体类型的资源总数
        Map<Integer, Long> total = Maps.newHashMap();
        total.put(MediaType.AUDIO, Long.valueOf(0));
        total.put(MediaType.VEDIO, Long.valueOf(0));
        total.put(MediaType.PICTURE, Long.valueOf(0));
        total.put(MediaType.TEXT, Long.valueOf(0));

        Map<Integer,Map<String,Long>> mediaTypeCount = new HashMap<>();

        long count = 0;

        log.debug("循环统计数据:Map<String, Object> info : infoList");
        //循环统计数据
        for (Map<String, Object> info : infoList) {
            String mediaType = (String) info.get("mediaType");
            long rscTotal = (Long)info.get("total");

            log.debug("循环媒体类型数据:Map.Entry<Integer, String> entry : MediaType.map.entrySet()");
            //循环媒体类型数据
            for (Map.Entry<Integer, String> entry : MediaType.map.entrySet()) {
                //匹配到媒体类型
                if (entry.getValue().contains(mediaType)) {
                    log.debug("匹配到媒体类型:entry.getValue().contains(mediaType)");

                    int key = entry.getKey();

                    //追加各媒体类型资源总数
                    total.put(key, total.get(key) + rscTotal);

                    //插入具体媒体类型的资源数量
                    if(mediaTypeCount.containsKey(key)){
                        log.debug("匹配到指定媒体类型的统计数据:mediaTypeCount.containsKey(key)");

                        mediaTypeCount.get(key).put(mediaType,rscTotal);
                    }else{
                        log.debug("未匹配到指定媒体类型的统计数据:!mediaTypeCount.containsKey(key)");

                        Map<String,Long> mediaCount = new HashMap<>();
                        mediaCount.put(mediaType,rscTotal);

                        mediaTypeCount.put(key,mediaCount);
                    }
                }
            }

            //追加总资源数量
            count += rscTotal;
        }

        //组合统计结果
        Map<String, Object> result = Maps.newHashMap();

        //插入资源总数
        result.put("total", count);

        //媒体数量统计结果
        List<Map<String, Object>> info = Lists.newArrayList();

        log.debug("循环统计数据，获取编号和数量");
        //循环统计数据，获取编号和数量
        for (Map.Entry<Integer, Long> entry : total.entrySet()) {
            Map<String, Object> entity = Maps.newHashMap();

            entity.put("id", entry.getKey());
            entity.put("count", entry.getValue());

            //匹配到统计数据
            if(mediaTypeCount.containsKey(entry.getKey())){
                log.debug("匹配到指定媒体类型的统计数据");

                entity.put("drilldown",mediaTypeCount.get(entry.getKey()));
            }

            info.add(entity);
        }

        result.put("info", info);

        return result;
    }

    /**
     * 获取群组资源统计数据
     * @param tag 标记（0：我的资源，1：我的收藏）
     * @param groupType 群组类型（0非群组 1课程群组 2专业群组 3班级群组）
     * @param keyword 搜索关键字
     * @return List
     *
     * @author fanruiping
     * @since 2015-05-06
     */
    public List<Map<String, Object>> getGroupResourceStatistics(int tag,int groupType,String keyword){
        Long userId = Long.valueOf(0);//创建人编号
        int role = 2;//创建人角色
        List<Long> rscIds = new ArrayList<>();

        //我的资源
        if(0 == tag){
            log.debug("获取的是我添加的资源:0 == tag");

            userId = webContext.getUserId();

            role = 0;

            //判断当前用户为学生
            if(Roles.STUDENT ==  webContext.getRole()){
                log.debug("当前用户的角色为学生:Roles.STUDENT ==  webContext.getRole()");

                role = 1;
            }
        }else {
            log.debug("获取的是我收藏的资源:1 == tag");

            //获取当前用户收藏资源
            rscIds = getCollectRscIds(Long.valueOf(0),groupType);

            if(rscIds.isEmpty()){
                log.debug("未获取到收藏的资源编号集合:rscIds.isEmpty()");

                return new ArrayList<>();
            }
        }

        Map<Long,Long> groupResource = resourceDao.getTotalByGroup(userId,role,groupType,keyword,rscIds);

        //判断是否获取到数据
        if(groupResource.isEmpty()){
            log.debug("未获取到群组资源数量统计数据:groupResource.isEmpty()");

            return new ArrayList<>();
        }

        //存储群组名称集合
        Map<Long,String> names = new HashMap<>();

        //群组类型为班级
        if(3 == groupType){
            log.debug("群组类型为班级群组:3 == groupType");

            names = classDao.getNameByIds(groupResource.keySet());
        }else if(0 == groupType || 2 == groupType){//群组类型为非群组或专业群组
            log.debug("群组类型为专业资源或专业群组:0 == groupType || 2 == groupType");

            names = specialtyDao.getNamesByIds(groupResource.keySet());
        }else {//课程群组
            log.debug("群组类型为课程群组");

            names = courseGroupDao.getNamesByIds(groupResource.keySet());
        }

        List<Map<String,Object>> result = new ArrayList<>();

        log.debug("循环插入群组编号、名称和资源数量:Long groupId : groupResource.keySet()");
        //循环插入群组编号、名称和资源数量
        for (Long groupId : groupResource.keySet()){
            Map<String,Object> data = new HashMap<>();
            data.put("id",groupId);
            data.put("name",names.get(groupId));
            data.put("count", groupResource.get(groupId));

            result.add(data);
        }

        return result;
    }

    /**
     * 获取当前用户收藏的资源编号集合
     * @param groupId 群组编号
     * @param groupType 群组类型
     * @return List
     *
     * @author fanruiping
     * @since 2015-05-07
     */
    private List<Long> getCollectRscIds(Long groupId,int groupType){
        List<Long> rscIds = new ArrayList<>();

        //判断用户是否是学生
        if(webContext.getRole() == Roles.STUDENT){
            log.debug("当前用户为学生:webContext.getRole() == Roles.STUDENT");

            //判断是否传递了群组编号
            if(groupId != 0){
                log.debug("限制群组编号:groupId != 0");

                rscIds = studentRscDao.getAll(webContext.getUserId(),groupId,groupType);
            }else{
                log.debug("不限制群组编号:groupId == 0");

                List<Long> groupIds = new ArrayList<>();

                //课程群组
                if(groupType == 1){
                    log.debug("群组类型为课程群组:groupType == 1");

                    groupIds = courseGroupDao.getIdsForStudent(webContext.getAccount());
                }

                rscIds = studentRscDao.getAll(webContext.getUserId(), groupType,groupIds);
            }
        }else{
            log.debug("当前用户是教师:webContext.getRole() != Roles.STUDENT");

            //限制群组编号
            if(groupId != 0){
                log.debug("获取教师的专业资源数据");

                rscIds = teacherRscDao.getAll(webContext.getUserId(),groupId,groupType);
            }else{
                log.debug("获取教师的群组类型数据:groupId == 0");

                List<Long> groupIds = new ArrayList<>();

                //专业资源或专业群组
                if(0 == groupType || 2 == groupType){
                    log.debug("群组类型为非群组或专业资源:0 == groupType || 2 == groupType");

                    groupIds = specialtyDao.getAllIds();
                }else if(1 == groupType){//课程群组
                    log.debug("群组类型为课程群组:1 == groupType");

                    groupIds = courseGroupDao.getIdsForTeacher(webContext.getAccount());
                }else if(3 == groupType){//班级群组
                    log.debug("群组类型为班级群组:3 == groupType");

                    groupIds = classDao.getIdsByTeacherNum(webContext.getAccount());
                }

                rscIds = teacherRscDao.getAll(webContext.getUserId(),groupType,groupIds);
            }
        }

        return rscIds;
    }

    /**
     * 获取我（创建或收藏）的资源列表
     * @param tag 标记（0：我创建，1：我收藏）
     * @param groupId 群组编号（0：全部）
     * @param groupType 群组类型（0：专业、1：课程、2：专业群组、3：班级）
     * @param mediaType 媒体类型
     * @param status 状态（0：所有、1：未审核、2：通过、3：忽略、4：未完成、5：无效）
     * @param type 资源类型
     * @param page 页码
     * @param pageSize 分页
     * @return Page
     *
     * @author fanruiping
     * @since 2015-05-06
     */
    public Page<Resource> getMyResourceList(int tag,Long groupId,int groupType,int mediaType,int status,int type,String keyword,int page,int pageSize){
        //判断用户角色
        if(webContext.getRole() == Roles.COLLEGE_USER || (groupType == 2 && webContext.getRole() == Roles.STUDENT)){
            log.debug("当前用户为院级用户或当前用户为学生且群组类型为专业群组，无权查看该数据");

            throw new ServiceException("当前用户无权查看该数据");
        }

        Long userId = Long.valueOf(0);//创建人编号
        int role = 2;//创建人角色
        List<Long> rscIds = new ArrayList<>();

        //我的资源
        if(0 == tag){
            log.debug("获取当前用户创建的资源:0 == tag");

            userId = webContext.getUserId();

            role = 0;

            //判断当前用户为学生
            if(Roles.STUDENT ==  webContext.getRole()){
                log.debug("当前用户为学生:Roles.STUDENT ==  webContext.getRole()");

                role = 1;
            }
        }else{
            log.debug("获取当前用户收藏的资源:1 == tag");

            //获取当前用户收藏资源编号集合
            rscIds = getCollectRscIds(groupId,groupType);

            if(rscIds.isEmpty()){
                log.debug("当前用户未收藏资源:rscIds.isEmpty()");

                return new Page<>();
            }
        }

        //获取媒体类型集合
        String mediaStr = MediaType.map.get(mediaType);
        List<String> mediaList = Lists.newArrayList();

        //媒体类型字符串不为null
        if (mediaStr != null) {
            log.debug("媒体类型字符串不为null:mediaStr != null");

            mediaList = Arrays.asList(StringUtils.split(mediaStr,":"));
        }

        Page<Resource> resourcePage = resourceDao.getListForMine(userId,role,groupId,mediaList,status,type,keyword,groupType,rscIds,page,pageSize);

        return resourcePage;
    }

    /**
     * 当前用户创建的资源类型下的资源数量统计
     * @param groupId 群组编号(0:全部)
     * @param groupType 群组类型（0：专业、1：课程、2：专业群组、3：班级）
     * @param tag 标记（0：我的；1收藏）
     * @param keyword 搜索关键字
     * @return List
     *
     * @author fanruiping
     * @since 2015-05-07
     */
    public List<Map<String,Object>> getTypeStatisticsForMine(Long groupId,int groupType,int tag,String keyword){
        //判断用户角色
        if(webContext.getRole() == Roles.COLLEGE_USER || (groupType == 2 && webContext.getRole() == Roles.STUDENT)){
            log.debug("当前用户为院级用户或当前用户为学生且群组类型为专业群组，无权查看该数据");

            throw new ServiceException("当前用户无权查看该数据");
        }

        Long userId = Long.valueOf(0);//创建人编号
        int role = 2;//创建人角色
        List<Long> rscIds = new ArrayList<>();

        //我的资源
        if(0 == tag){
            log.debug("获取当前用户创建的资源:0 == tag");

            userId = webContext.getUserId();

            role = 0;

            //判断当前用户为学生
            if(Roles.STUDENT ==  webContext.getRole()){
                log.debug("当前用户为学生:Roles.STUDENT ==  webContext.getRole()");

                role = 1;
            }
        }else{
            log.debug("获取当前用户收藏的资源:1 == tag");

            //获取当前用户收藏资源编号集合
            rscIds = getCollectRscIds(groupId,groupType);

            //资源编号集合为空
            if(rscIds.isEmpty()){
                log.debug("当前用户未收藏资源:rscIds.isEmpty()");

                return new ArrayList<>();
            }
        }

        Map<Long,Long> typeStatistics = resourceDao.getTotalForTypeAndGroup(userId,role,keyword,rscIds,groupId,groupType);

        //资源类型资源数量统计为空
        if(typeStatistics.isEmpty()){
            log.debug("资源类型资源数量统计为空:typeStatistics.isEmpty()");

            return new ArrayList<>();
        }

        Map<Long,String> names = resourceTypeDao.getNameByIds(typeStatistics.keySet());

        List<Map<String,Object>> result = new ArrayList<>();

        log.debug("循环资源类型资源数量统计数据，获取类型编号、名称和资源数量");
        //循环资源类型资源数量统计数据
        for (Long typeId : typeStatistics.keySet()){
            Map<String,Object> data = new HashMap<>();
            data.put("id",typeId);
            data.put("name",names.get(typeId));
            data.put("count", typeStatistics.get(typeId));

            result.add(data);
        }

        return result;
    }
    //</editor-fold>
}
